package com.optional;

import com.optional.entity.School;
import com.optional.entity.Student;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
//        simple();
        testChain();
    }

    /**
     * 简单示例
     */
    private static void simple() {
        List<String> notEmptyList = Arrays.asList("apple", "banana", "orange");
        List<String> emptyList = null;
        // 1.构造Optional对象:of()方法传入值，ofNullable()方法传入可能为null的值
        // 推荐使用ofNullable()方法，因为它可以兼容null值，防止NPE
        Optional<List<String>> notEmptyOptional = Optional.ofNullable(notEmptyList);
        Optional<List<String>> emptyOptional = Optional.ofNullable(emptyList);
        // 2.isPresent()方法判断值是否存在
        boolean trueValue = notEmptyOptional.isPresent();//true
        boolean falseValue = emptyOptional.isPresent();//false
        System.out.println("notEmptyOptional = " + trueValue);
        System.out.println("emptyOptional = " + falseValue);

        // 3.get()：获取值,如果值不存在，则抛出NoSuchElementException异常
        List<String> notEmptyValue = notEmptyOptional.get();
        System.out.println("notEmptyValue = " + notEmptyValue);

        // 4.orElse(默认值，无论optional的值是否存在，一定会执行)：值不存在时，返回设置的默认值
        List<String> orElse1 = notEmptyOptional.orElse(setDefaultValue("notEmptyOptional"));//会输出
        List<String> orElse2 = emptyOptional.orElse(setDefaultValue("emptyOptional"));//会输出

        // 5.orElseGet(默认值，只有当optional的值不存在时，才会执行)：如果值不存在，则执行Supplier接口的get方法
        List<String> orElseGet1 = notEmptyOptional.orElseGet(() -> setDefaultValue("notEmptyOptional"));//不会输出
        List<String> orElseGet2 = emptyOptional.orElseGet(() -> setDefaultValue("emptyOptional"));//会输出

        // 6.orElseThrow(值不存在，抛出异常)：如果值不存在，则抛出异常
        List<String> orElseThrow1 = notEmptyOptional.orElseThrow(IllegalArgumentException::new);
//        List<String> orElseThrow2 = emptyOptional.orElseThrow(IllegalArgumentException::new);

        // 7.ifPresent(Consumer接口)：如果值存在，则执行Consumer接口的accept方法
        notEmptyOptional.ifPresent(list -> System.out.println("notEmptyOptional = " + list));//会输出
        emptyOptional.ifPresent(list -> System.out.println("emptyOptional = " + list));
    }

    /**
     * 设置默认值
     *
     * @return {@link List }<{@link String }>
     */
    public static List<String> setDefaultValue(String... args) {
        System.out.println("setDefaultValue args = " + Arrays.toString(args));
        return Arrays.asList(args);
    }

    /**
     * 测试链式编程
     */
    public static void testChain() {
        // 初始化数据
        Student student1 = new Student("Tom", 18, new School("USA", "4568"));
        Student student2 = new Student("Ami", 18, new School("USA", "4569"));
        Student student3 = new Student("张三", 18, new School("CHINA", "123"));
        Student student4 = new Student("李四", 18, null);
        Student student5 = new Student("王五", 18, new School("CHINA", "125"));
        List<Student> list = Arrays.asList(student1, student2, student3, student4, student5);
        // 链式编程，筛选出所有学校地址为CHINA的学生，使用optional进行封装
        List<Student> result = list.stream()
               .filter(student -> Optional.ofNullable(student.getSchool())
                       .map(School::getAddress)
                       .filter(address -> "CHINA".equals(address))
                       .isPresent())
               .collect(Collectors.toList());
        result.forEach(item -> System.out.println(item.getName()));
    }
}